home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / text / hyper / hsc_source.lha / hsc / source / hsclib / idref.c < prev    next >
C/C++ Source or Header  |  1996-10-14  |  5KB  |  223 lines

  1. /*
  2.  * hsclib/idref.c
  3.  *
  4.  * functions for id-references
  5.  *
  6.  * Copyright (C) 1996  Thomas Aglassinger
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  *
  22.  * updated: 14-Oct-1996
  23.  * created: 12-Apr-1995
  24.  *
  25.  */
  26.  
  27. #include "hsclib/inc_base.h"
  28.  
  29. #include <stdarg.h>
  30. #include "ugly/ustrlist.h"
  31.  
  32. #include "hscprj/document.h"
  33. #define NOEXTERN_HSCLIB_ID_H
  34. #include "hsclib/idref.h"
  35.  
  36. #if DEBUG_ID
  37. #define DIHP(x) if ( hp->debug ) x
  38. #define DI(x)   x
  39. #else
  40. #define DIHP(x)                 /* nufin */
  41. #define DI(x)                   /* nufin */
  42. #endif
  43.  
  44. /* hsc_msg_unknown_id: warning about unknown id-refrence */
  45. VOID hsc_msg_unknown_id(HSCPRC * hp, STRPTR filename, STRPTR id)
  46. {
  47.     if (filename)
  48.         hsc_message(hp, MSG_UNKN_ID, "unknown id `%s#%s'",
  49.                     filename, id);
  50.     else
  51.         hsc_message(hp, MSG_UNKN_ID, "unknown id %q", id);
  52. }
  53.  
  54. /* macros for local compare-callbacks */
  55. #define cmp_idname cmp_string_node
  56. #define cmp_idref cmp_string_node
  57. #define cmp_id_local cmp_string_node
  58.  
  59. /*
  60.  *
  61.  * new- and del-methodes
  62.  *
  63.  */
  64.  
  65. /*
  66.  * del/new_idref
  67.  */
  68.  
  69. /* del_idref: remove referenced id */
  70. VOID del_idref(APTR data)
  71. {
  72.     IDREF *idref = (IDREF *) data;
  73.  
  74.     ufreestr(idref->name);
  75.     del_infilepos(idref->fpos);
  76.     ufree(idref);
  77. }
  78.  
  79. /* new_id_local: create new reference to local id  */
  80. static IDREF *new_idref(STRPTR id, INFILEPOS * fpos)
  81. {
  82.     IDREF *newid = (IDREF *) umalloc(sizeof(IDREF));
  83.  
  84.     newid->name = strclone(id);
  85.     newid->fpos = fpos;
  86.  
  87.     return (newid);
  88. }
  89.  
  90. VOID prt_idref(FILE * stream, APTR data)
  91. {
  92.     IDREF *idref = (IDREF *) data;
  93.     INFILEPOS *fpos = idref->fpos;
  94.  
  95.     fprintf(stream, "`%s' at (%lu,%lu)\n",
  96.             idref->name, ifp_get_y(fpos), ifp_get_x(fpos));
  97. }
  98.  
  99. /*
  100.  * add_local_iddef
  101.  *
  102.  * define a new local ID that can be refered to
  103.  */
  104. BOOL add_local_iddef(HSCPRC * hp, STRPTR id)
  105. {
  106.     INFILEPOS *fpos = new_infilepos(hp->inpf);
  107.     HSCIDD *iddef = find_iddef(hp->project->document, id);
  108.  
  109.     DIHP(fprintf(stderr, DHL "add ref to id `%s' at `%s' (%lu,%lu)\n",
  110.                  id, ifp_get_fname(fpos),
  111.                  ifp_get_y(fpos), ifp_get_x(fpos)));
  112.  
  113.     /* check for duplicate definition */
  114.  
  115.     if (iddef)
  116.     {
  117.         /* duplicate definition */
  118.         DIHP(fprintf(stderr, DHL "    duplicate definition\n"));
  119.  
  120.         hsc_message(hp, MSG_REDEFINE_ID,
  121.                     "local id %q already declared", id);
  122.  
  123.         set_infilepos(hp->inpf, iddef->fpos);
  124.         hsc_message(hp, MSG_REDEFINE_ID,
  125.                     "(location of previous declaration)");
  126.  
  127.         set_infilepos(hp->inpf, fpos);
  128.         del_infilepos(fpos);
  129.     }
  130.     else
  131.     {
  132.         /* remember new local id */
  133.         iddef = app_iddef(hp->project->document, id);
  134.         iddef->caller = fpos2caller(fpos);
  135.         iddef->fpos = fpos;
  136.  
  137.         DIHP(fprintf(stderr, DHL "    append to local iddefs\n"));
  138.     }
  139.  
  140.     return (TRUE);
  141. }
  142.  
  143. /*
  144.  * check_id_local
  145.  *
  146.  * append id to idref-list so it as checked when
  147.  * check_all_local_idref() is called
  148.  */
  149. VOID add_local_idref(HSCPRC * hp, STRPTR id)
  150. {
  151.     INFILEPOS *fpos = new_infilepos(hp->inpf);
  152.  
  153.     DIHP(fprintf(stderr, DHL "  check id: `#%s' (local)\n", id));
  154.     DIHP(fprintf(stderr, DHL "    append to idref\n"));
  155.     app_dlnode(hp->idrefs, new_idref(id, fpos));
  156. }
  157.  
  158. /*
  159.  * check_local_idref
  160.  */
  161. static BOOL check_local_idref(HSCPRC * hp, IDREF * idref)
  162. {
  163.     HSCIDD *iddef = find_iddef(hp->project->document, idref->name);
  164.     BOOL found = FALSE;
  165.  
  166.     if (iddef)
  167.     {
  168.         found = TRUE;
  169.         DIHP(fprintf(stderr, DHL " local id ok: `%s'\n", idref->name));
  170.     }
  171.     else
  172.     {
  173.         DIHP(
  174.                 {
  175.                 INFILEPOS * fpos = idref->fpos;
  176.                 fprintf(stderr, DHL " local id unknown: `%s' (%lu,%lu)\n",
  177.                         idref->name, ifp_get_y(fpos), ifp_get_x(fpos));
  178.                 }
  179.         );
  180.  
  181.         set_infilepos(hp->inpf, idref->fpos);
  182.         hsc_msg_unknown_id(hp, NULL, idref->name);
  183.     }
  184.  
  185.     return (found);
  186. }
  187.  
  188. /*
  189.  * check_all_local_idref
  190.  */
  191. BOOL check_all_local_idref(HSCPRC * hp)
  192. {
  193.     BOOL ok = TRUE;
  194.     DLNODE *nd = NULL;
  195.     INFILEPOS *infpos = new_infilepos(hp->inpf);
  196.  
  197.     DIHP(fprintf(stderr, DHL "check local IDs\n"));
  198.  
  199.     DIHP(
  200.             {
  201.  
  202.             fprintf(stderr, DHL " local IDs defined:\n");
  203.             fprintf_dllist(stderr, hp->project->document->iddefs, prt_iddef);
  204.             fprintf(stderr, DHL " local IDs referenced:\n");
  205.             fprintf_dllist(stderr, hp->idrefs, prt_idref);
  206.  
  207.             }
  208.     );
  209.  
  210.     nd = dll_first(hp->idrefs);
  211.     while (nd)
  212.     {
  213.         check_local_idref(hp, ((IDREF *) nd->data));
  214.         nd = dln_next(nd);
  215.     }
  216.  
  217.     set_infilepos(hp->inpf, infpos);
  218.     del_infilepos(infpos);
  219.  
  220.     return (ok);
  221. }
  222.  
  223.